
#include <queBase.h>

int queOptInit(void *qptr, queOptType optSize)
{
    struct queOptStruct *qopt = (struct queOptStruct *)qptr;
    if (qopt == NULL)
    {
        return -1;
    }
    memset(qopt, 0, sizeof(struct queOptStruct));
    qopt->bfSize = optSize - queOptHeadSize;
    return 0;
}
queOptType queOptWrite(void *qptr, const uint8_t *iobuf, queOptType len)
{
    queOptType i;
    struct queOptStruct *qopt = (struct queOptStruct *)qptr;
    if (!(qopt && iobuf))
    {
        return 0;
    }
    if (len >= qopt->bfSize)
    {
        // printf("queOptWrite len err %p, %u > %u\n", qptr, len, qopt->bfSize);
    }
    for (i = 0; i < len; i++)
    {
        qopt->bfSave[qopt->widx] = iobuf[i];
        qopt->widx = CYCLE_ADD(qopt->widx, 1, qopt->bfSize);
    }
    return len;
}
queOptType queOptSize(void *qptr, uint8_t rdChnl)
{
    struct queOptStruct *qopt = (struct queOptStruct *)qptr;
    if (!(qopt))
    {
        return 0;
    }
    if (rdChnl >= QUE_OPT_READ_SIZE)
    {
        return 0;
    }
    // logdebugc("total=%d,w=%d,r=%d,size=%d", qopt->bfSize, qopt->widx, qopt->ridx[rdChnl],
    //          (qopt->widx + qopt->bfSize - qopt->ridx[rdChnl]) % qopt->bfSize);
    return (qopt->widx + qopt->bfSize - qopt->ridx[rdChnl]) % qopt->bfSize;
}
queOptType queOptRead(void *qptr, uint8_t rdChnl, uint8_t *iobuf, queOptType len)
{
    struct queOptStruct *qopt = (struct queOptStruct *)qptr;
    queOptType i, tmplen;
    if (!(qopt && iobuf))
    {
        return 0;
    }
    tmplen = queOptSize(qopt, rdChnl);
    if (tmplen < 1)
    {
        return 0;
    }
    tmplen = tmplen > len ? len : tmplen;
    for (i = 0; i < tmplen; i++)
    {
        iobuf[i] = qopt->bfSave[qopt->ridx[rdChnl]];
        qopt->ridx[rdChnl] = CYCLE_ADD(qopt->ridx[rdChnl], 1, qopt->bfSize);
    }
    return tmplen;
}
queOptType queOptRdFix(void *qptr, uint8_t rdChnl, uint8_t *iobuf, queOptType len)
{
    struct queOptStruct *qopt = (struct queOptStruct *)qptr;
    if (!(qopt && iobuf))
    {
        return 0;
    }
    if (queOptSize(qopt, rdChnl) < len)
    {
        return 0;
    }
    return queOptRead(qopt, rdChnl, iobuf, len);
}